import time
import threading
import pygame
import serial  # pyserial
from BrainLinkParser import BrainLinkParser   # .pyd 必须在同一目录或 Python path 中

# ============== 配置 ==============
COM_PORT = "COM5"          # ←←← 重要！改成你 Brainlink Pro 的实际串口（设备管理器里查看“Bluetooth Serial Port”或类似）
BAUDRATE = 115200

# 初始化 pygame 音频（播放钢琴音）
pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=512)
pygame.mixer.set_num_channels(8)

# 这里先用简单 beep 声音测试（无需下载 wav 文件）
# 后面可以换成真实钢琴音
def play_note(freq=523, duration=0.2, volume=0.6):   # 523Hz ≈ C5
    sample_rate = 44100
    t = pygame.sndarray.make_sound(
        (pygame.sndarray.samples(
            pygame.mixer.Sound(buffer=pygame.sndarray.array(
                pygame.mixer.Sound(
                    pygame.sndarray.make_sound(
                        (32767 * pygame.sndarray.samples(
                            pygame.mixer.Sound(
                                buffer=b'\x00' * int(sample_rate * duration)
                            )
                        ))
                    )
                ))
            ))
        ) * volume).astype('int16')
    
    # 更简单的方式：用正弦波生成音调
    import numpy as np
    arr = np.sin(2 * np.pi * freq * np.linspace(0, duration, int(sample_rate * duration))) * 32767 * volume
    sound = pygame.sndarray.make_sound(arr.astype('int16'))
    sound.play()

# ============== Brainlink 回调函数 ==============
def on_eeg(data):
    # data 是 BrainLinkData 对象，包含 attention, meditation 等
    attention = getattr(data, 'attention', 0)
    meditation = getattr(data, 'meditation', 0)
    blink = getattr(data, 'blinkStrength', 0)   # 不同版本字段可能不同

    print(f"专注度: {attention:3d} | 放松度: {meditation:3d} | 眨眼: {blink}")

    # 脑电波转钢琴映射（可自行调整）
    if attention > 65:          # 专注 → 较高音、较活泼
        freq = 523 + (attention - 65) * 8   # C5 开始往上
        play_note(freq, duration=0.15, volume=0.7)

    elif meditation > 55:       # 放松 → 较低音、较柔和
        freq = 330 + (meditation - 55) * 3   # E4 附近
        play_note(freq, duration=0.4, volume=0.6)

    if blink > 70:              # 眨眼 → 强音或高音强调
        play_note(784, duration=0.1, volume=0.9)   # 高音 G5

# ============== 创建 Parser 并绑定回调 ==============
parser = BrainLinkParser(eeg_callback=on_eeg)   # 可以根据需要加其他回调

# ============== 串口读取线程 ==============
def read_serial():
    try:
        ser = serial.Serial(COM_PORT, BAUDRATE, timeout=1)
        print(f"✅ 已打开串口 {COM_PORT}，请戴上 Brainlink Pro 并确保蓝牙已连接")
        print("🎹 用意念开始弹钢琴吧！专注/放松会改变音调，眨眼有强调音")

        while True:
            if ser.in_waiting:
                msg = ser.read(ser.in_waiting)
                if msg:
                    parser.parse(msg)          # 关键：把串口数据传给 Parser 解析
            time.sleep(0.001)
    except serial.SerialException as e:
        print(f"❌ 串口打开失败: {e}")
        print("请检查：")
        print("1. COM 口号是否正确？（设备管理器查看）")
        print("2. Brainlink Pro 是否已开机并通过蓝牙配对？")
        print("3. 是否有其他程序占用了该串口？")
    except Exception as e:
        print(f"串口读取出错: {e}")

# 启动串口读取线程
threading.Thread(target=read_serial, daemon=True).start()

print("程序启动中... 按 Ctrl+C 退出")

try:
    while True:
        time.sleep(0.1)
except KeyboardInterrupt:
    pygame.mixer.quit()
    print("\n🎹 已停止演奏")